<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>JavaKeeper</title>
    <meta name="generator" content="VuePress 1.5.4">
    <link rel="icon" href="/icon.svg">
    <script>
        var _hmt = _hmt || [];
        (function() {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?a949a9b30eb86ac0159e735ff8670c03";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
            // 引入谷歌,不需要可删除这段
            var hm1 = document.createElement("script");
            hm1.src = "https://www.googletagmanager.com/gtag/js?id=UA-169923503-1";
            var s1 = document.getElementsByTagName("script")[0]; 
            s1.parentNode.insertBefore(hm1, s1);
        })();
        // 谷歌加载,不需要可删除
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'UA-169923503-1');
    </script>
    <meta name="description" content="">
    <meta name="keywords" content="JavaKeeper,Java,Java开发,算法,blog">
    <link rel="preload" href="/assets/css/0.styles.91f57736.css" as="style"><link rel="preload" href="/assets/js/app.447d4224.js" as="script"><link rel="preload" href="/assets/js/3.9d76740c.js" as="script"><link rel="preload" href="/assets/js/1.c4fd7d2e.js" as="script"><link rel="preload" href="/assets/js/102.c9485235.js" as="script"><link rel="prefetch" href="/assets/js/10.8cf3be2c.js"><link rel="prefetch" href="/assets/js/100.74f35ab8.js"><link rel="prefetch" href="/assets/js/101.7a062346.js"><link rel="prefetch" href="/assets/js/103.d88a3805.js"><link rel="prefetch" href="/assets/js/104.6e034144.js"><link rel="prefetch" href="/assets/js/105.d22f7450.js"><link rel="prefetch" href="/assets/js/106.a6cb54b0.js"><link rel="prefetch" href="/assets/js/107.7b65e72b.js"><link rel="prefetch" href="/assets/js/108.eb5804bb.js"><link rel="prefetch" href="/assets/js/109.05f775e5.js"><link rel="prefetch" href="/assets/js/11.c54ae13c.js"><link rel="prefetch" href="/assets/js/110.51d3d641.js"><link rel="prefetch" href="/assets/js/111.022b64a7.js"><link rel="prefetch" href="/assets/js/112.da8afd52.js"><link rel="prefetch" href="/assets/js/113.05a17b18.js"><link rel="prefetch" href="/assets/js/114.8960d913.js"><link rel="prefetch" href="/assets/js/115.67919f68.js"><link rel="prefetch" href="/assets/js/116.62b0cd71.js"><link rel="prefetch" href="/assets/js/117.ebac3eff.js"><link rel="prefetch" href="/assets/js/118.ecd629bd.js"><link rel="prefetch" href="/assets/js/119.a09a0897.js"><link rel="prefetch" href="/assets/js/12.60aa3b24.js"><link rel="prefetch" href="/assets/js/120.bf639d3d.js"><link rel="prefetch" href="/assets/js/121.b89d0c8e.js"><link rel="prefetch" href="/assets/js/122.1a75ff83.js"><link rel="prefetch" href="/assets/js/123.d2127132.js"><link rel="prefetch" href="/assets/js/124.2caff9e0.js"><link rel="prefetch" href="/assets/js/125.9b9f966a.js"><link rel="prefetch" href="/assets/js/126.58cdfb3d.js"><link rel="prefetch" href="/assets/js/127.8ef09c53.js"><link rel="prefetch" href="/assets/js/128.efdc2ae4.js"><link rel="prefetch" href="/assets/js/129.e35cbc57.js"><link rel="prefetch" href="/assets/js/13.125c13a0.js"><link rel="prefetch" href="/assets/js/130.f01a55e3.js"><link rel="prefetch" href="/assets/js/131.65205f4a.js"><link rel="prefetch" href="/assets/js/132.f42c5a0a.js"><link rel="prefetch" href="/assets/js/133.9ba468b3.js"><link rel="prefetch" href="/assets/js/134.7b597ba9.js"><link rel="prefetch" href="/assets/js/135.fb828b9a.js"><link rel="prefetch" href="/assets/js/136.3887532f.js"><link rel="prefetch" href="/assets/js/137.549bae01.js"><link rel="prefetch" href="/assets/js/138.db8d423d.js"><link rel="prefetch" href="/assets/js/139.dbaf2267.js"><link rel="prefetch" href="/assets/js/14.bd1d0b0d.js"><link rel="prefetch" href="/assets/js/140.6cb65fdc.js"><link rel="prefetch" href="/assets/js/141.9bd6cc4b.js"><link rel="prefetch" href="/assets/js/142.552db5ed.js"><link rel="prefetch" href="/assets/js/143.2c9f2bf4.js"><link rel="prefetch" href="/assets/js/144.fba98a15.js"><link rel="prefetch" href="/assets/js/145.c42f3a21.js"><link rel="prefetch" href="/assets/js/146.596d4d33.js"><link rel="prefetch" href="/assets/js/147.c48ae5c1.js"><link rel="prefetch" href="/assets/js/148.71064871.js"><link rel="prefetch" href="/assets/js/149.16582d21.js"><link rel="prefetch" href="/assets/js/15.f247873b.js"><link rel="prefetch" href="/assets/js/150.ead09aca.js"><link rel="prefetch" href="/assets/js/151.971fdf4b.js"><link rel="prefetch" href="/assets/js/152.369c9362.js"><link rel="prefetch" href="/assets/js/153.371edd15.js"><link rel="prefetch" href="/assets/js/154.e090b491.js"><link rel="prefetch" href="/assets/js/155.c68bf602.js"><link rel="prefetch" href="/assets/js/156.304aea8d.js"><link rel="prefetch" href="/assets/js/157.83beef7f.js"><link rel="prefetch" href="/assets/js/158.bb1794b0.js"><link rel="prefetch" href="/assets/js/159.2d54e792.js"><link rel="prefetch" href="/assets/js/16.04336c71.js"><link rel="prefetch" href="/assets/js/160.99d56586.js"><link rel="prefetch" href="/assets/js/161.edf660aa.js"><link rel="prefetch" href="/assets/js/162.0b84606e.js"><link rel="prefetch" href="/assets/js/163.b59e0d60.js"><link rel="prefetch" href="/assets/js/164.d9eb8228.js"><link rel="prefetch" href="/assets/js/165.ca624c79.js"><link rel="prefetch" href="/assets/js/166.025b2ba1.js"><link rel="prefetch" href="/assets/js/167.abc982cc.js"><link rel="prefetch" href="/assets/js/168.27ca13dc.js"><link rel="prefetch" href="/assets/js/169.41e753a2.js"><link rel="prefetch" href="/assets/js/17.43b3c1c8.js"><link rel="prefetch" href="/assets/js/170.626319e1.js"><link rel="prefetch" href="/assets/js/171.a221dddf.js"><link rel="prefetch" href="/assets/js/172.464b2361.js"><link rel="prefetch" href="/assets/js/173.96a3afee.js"><link rel="prefetch" href="/assets/js/174.116607c2.js"><link rel="prefetch" href="/assets/js/175.ea3e8659.js"><link rel="prefetch" href="/assets/js/176.7d7b8afc.js"><link rel="prefetch" href="/assets/js/177.a6e00aa0.js"><link rel="prefetch" href="/assets/js/178.1f93afaf.js"><link rel="prefetch" href="/assets/js/179.3aa00dcd.js"><link rel="prefetch" href="/assets/js/18.d81b44d5.js"><link rel="prefetch" href="/assets/js/180.f8b2b75a.js"><link rel="prefetch" href="/assets/js/181.8e11258a.js"><link rel="prefetch" href="/assets/js/182.22243941.js"><link rel="prefetch" href="/assets/js/183.d051fdf6.js"><link rel="prefetch" href="/assets/js/184.a994075e.js"><link rel="prefetch" href="/assets/js/185.776c7e16.js"><link rel="prefetch" href="/assets/js/186.f1887955.js"><link rel="prefetch" href="/assets/js/187.da0d3626.js"><link rel="prefetch" href="/assets/js/188.8dfc358f.js"><link rel="prefetch" href="/assets/js/189.dcac5a59.js"><link rel="prefetch" href="/assets/js/19.1b3d66e1.js"><link rel="prefetch" href="/assets/js/190.c7e413d0.js"><link rel="prefetch" href="/assets/js/191.d9806121.js"><link rel="prefetch" href="/assets/js/192.869791da.js"><link rel="prefetch" href="/assets/js/193.2d74c4c8.js"><link rel="prefetch" href="/assets/js/194.c73a1909.js"><link rel="prefetch" href="/assets/js/195.e8c74834.js"><link rel="prefetch" href="/assets/js/20.bd5949ec.js"><link rel="prefetch" href="/assets/js/21.3fcf98cf.js"><link rel="prefetch" href="/assets/js/22.2fa1e2e8.js"><link rel="prefetch" href="/assets/js/23.1ae64bb4.js"><link rel="prefetch" href="/assets/js/24.7bdf7387.js"><link rel="prefetch" href="/assets/js/25.392c436e.js"><link rel="prefetch" href="/assets/js/26.58acbd4b.js"><link rel="prefetch" href="/assets/js/27.c725bdd5.js"><link rel="prefetch" href="/assets/js/28.6c9bda1e.js"><link rel="prefetch" href="/assets/js/29.e656b537.js"><link rel="prefetch" href="/assets/js/30.2c326fc7.js"><link rel="prefetch" href="/assets/js/31.e6c9fa30.js"><link rel="prefetch" href="/assets/js/32.c9c88437.js"><link rel="prefetch" href="/assets/js/33.0c53373c.js"><link rel="prefetch" href="/assets/js/34.9821e543.js"><link rel="prefetch" href="/assets/js/35.de8253eb.js"><link rel="prefetch" href="/assets/js/36.d182f929.js"><link rel="prefetch" href="/assets/js/37.9fa79014.js"><link rel="prefetch" href="/assets/js/38.9bebff76.js"><link rel="prefetch" href="/assets/js/39.19a3a2d4.js"><link rel="prefetch" href="/assets/js/4.564edb9d.js"><link rel="prefetch" href="/assets/js/40.cca6955f.js"><link rel="prefetch" href="/assets/js/41.854cd09a.js"><link rel="prefetch" href="/assets/js/42.ca7b612f.js"><link rel="prefetch" href="/assets/js/43.87027d58.js"><link rel="prefetch" href="/assets/js/44.8c2b4f4b.js"><link rel="prefetch" href="/assets/js/45.dffb4e08.js"><link rel="prefetch" href="/assets/js/46.f58049a5.js"><link rel="prefetch" href="/assets/js/47.6854070c.js"><link rel="prefetch" href="/assets/js/48.6cd9fa3d.js"><link rel="prefetch" href="/assets/js/49.e8861afa.js"><link rel="prefetch" href="/assets/js/5.5c31d62f.js"><link rel="prefetch" href="/assets/js/50.703bffab.js"><link rel="prefetch" href="/assets/js/51.6655c373.js"><link rel="prefetch" href="/assets/js/52.deb2eb09.js"><link rel="prefetch" href="/assets/js/53.6e0ed77d.js"><link rel="prefetch" href="/assets/js/54.b05c58ad.js"><link rel="prefetch" href="/assets/js/55.49c8164e.js"><link rel="prefetch" href="/assets/js/56.a5574e6b.js"><link rel="prefetch" href="/assets/js/57.58cb0de4.js"><link rel="prefetch" href="/assets/js/58.52345112.js"><link rel="prefetch" href="/assets/js/59.663ce78d.js"><link rel="prefetch" href="/assets/js/6.a9df34ee.js"><link rel="prefetch" href="/assets/js/60.f06adde2.js"><link rel="prefetch" href="/assets/js/61.170255a1.js"><link rel="prefetch" href="/assets/js/62.9d120050.js"><link rel="prefetch" href="/assets/js/63.70cced6b.js"><link rel="prefetch" href="/assets/js/64.577f3548.js"><link rel="prefetch" href="/assets/js/65.c037b29d.js"><link rel="prefetch" href="/assets/js/66.7dd1045f.js"><link rel="prefetch" href="/assets/js/67.d3aa4d6c.js"><link rel="prefetch" href="/assets/js/68.526dbb61.js"><link rel="prefetch" href="/assets/js/69.58269266.js"><link rel="prefetch" href="/assets/js/7.6609d4d6.js"><link rel="prefetch" href="/assets/js/70.64108f1b.js"><link rel="prefetch" href="/assets/js/71.1e95e0a6.js"><link rel="prefetch" href="/assets/js/72.42e7ec94.js"><link rel="prefetch" href="/assets/js/73.dad4e1c5.js"><link rel="prefetch" href="/assets/js/74.28ea286a.js"><link rel="prefetch" href="/assets/js/75.dd6d4c6f.js"><link rel="prefetch" href="/assets/js/76.ca6539df.js"><link rel="prefetch" href="/assets/js/77.feb13b0e.js"><link rel="prefetch" href="/assets/js/78.321e90e6.js"><link rel="prefetch" href="/assets/js/79.68eb8fcf.js"><link rel="prefetch" href="/assets/js/8.396d51fd.js"><link rel="prefetch" href="/assets/js/80.4edb5321.js"><link rel="prefetch" href="/assets/js/81.735d7e57.js"><link rel="prefetch" href="/assets/js/82.fa120bdf.js"><link rel="prefetch" href="/assets/js/83.bf755f94.js"><link rel="prefetch" href="/assets/js/84.9b32070c.js"><link rel="prefetch" href="/assets/js/85.592aca7c.js"><link rel="prefetch" href="/assets/js/86.4dcd9e73.js"><link rel="prefetch" href="/assets/js/87.a9e546aa.js"><link rel="prefetch" href="/assets/js/88.2a423212.js"><link rel="prefetch" href="/assets/js/89.5f455115.js"><link rel="prefetch" href="/assets/js/9.adb074c6.js"><link rel="prefetch" href="/assets/js/90.5202da0a.js"><link rel="prefetch" href="/assets/js/91.02cee99d.js"><link rel="prefetch" href="/assets/js/92.f16bad0b.js"><link rel="prefetch" href="/assets/js/93.f933634f.js"><link rel="prefetch" href="/assets/js/94.8e7b1d65.js"><link rel="prefetch" href="/assets/js/95.ee0e4a0a.js"><link rel="prefetch" href="/assets/js/96.e21d78c2.js"><link rel="prefetch" href="/assets/js/97.c87e514e.js"><link rel="prefetch" href="/assets/js/98.d123ac92.js"><link rel="prefetch" href="/assets/js/99.92d1b416.js">
    <link rel="stylesheet" href="/assets/css/0.styles.91f57736.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container" data-v-3ba18f14><div data-v-3ba18f14><div id="loader-wrapper" class="loading-wrapper" data-v-041fef5b data-v-3ba18f14 data-v-3ba18f14><div class="loader-main" data-v-041fef5b><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div><div data-v-041fef5b></div></div> <!----> <!----></div> <div class="password-shadow password-wrapper-out" style="display:none;" data-v-68139a52 data-v-3ba18f14 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52>JavaKeeper</h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div class="hide" data-v-3ba18f14><header class="navbar" data-v-3ba18f14><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">JavaKeeper</span></a> <div class="links"><div class="color-picker"><a class="color-button"><i class="iconfont reco-color"></i></a> <div class="color-picker-menu" style="display:none;"><div class="mode-options"><h4 class="title">Choose mode</h4> <ul class="color-mode-options"><li class="dark">dark</li><li class="auto active">auto</li><li class="light">light</li></ul></div></div></div> <div class="search-box"><i class="iconfont reco-search"></i> <input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link router-link-active"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask" data-v-3ba18f14></div> <aside class="sidebar" data-v-3ba18f14><div class="personal-info-wrapper" data-v-5f6acefd data-v-3ba18f14><!----> <h3 class="name" data-v-5f6acefd>
    海星
  </h3> <div class="num" data-v-5f6acefd><div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Article</h6></div> <div data-v-5f6acefd><h3 data-v-5f6acefd>0</h3> <h6 data-v-5f6acefd>Tag</h6></div></div> <hr data-v-5f6acefd></div> <nav class="nav-links"><div class="nav-item"><a href="/java/" class="nav-link"><i class="iconfont undefined"></i>
  Java
</a></div><div class="nav-item"><a href="/data-structure-algorithms/" class="nav-link"><i class="iconfont undefined"></i>
  数据结构与算法
</a></div><div class="nav-item"><a href="/data-store/" class="nav-link"><i class="iconfont undefined"></i>
  数据存储与缓存
</a></div><div class="nav-item"><a href="/interview/" class="nav-link router-link-active"><i class="iconfont undefined"></i>
  直击面试
</a></div> <a href="https://github.com/Jstarfish/JavaKeeper" target="_blank" rel="noopener noreferrer" class="repo-link"><i class="iconfont reco-github"></i>
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav> <ul class="sidebar-links"><li><a href="/interview/Collections-FAQ.html" class="sidebar-link">Java集合面试</a></li><li><a href="/interview/JUC-FAQ.html" class="sidebar-link">Java 多线程面试</a></li><li><a href="/interview/JVM-FAQ.html" aria-current="page" class="active sidebar-link">JVM 面试</a></li><li><a href="/interview/MySQL-FAQ.html" class="sidebar-link">MySQL 面试</a></li><li><a href="/interview/Redis-FAQ.html" class="sidebar-link">Redis 面试</a></li><li><a href="/interview/Network-FAQ.html" class="sidebar-link">计算机网络面试</a></li><li><a href="/interview/Kafka-FAQ.html" class="sidebar-link">Kafka 面试</a></li><li><a href="/interview/ZooKeeper-FAQ.html" class="sidebar-link">Zookeeper 面试</a></li><li><a href="/interview/MyBatis-FAQ.html" class="sidebar-link">MyBatis 面试</a></li><li><a href="/interview/Spring-FAQ.html" class="sidebar-link">Spring 面试</a></li><li><a href="/interview/Design-Pattern-FAQ.html" class="sidebar-link">设计模式面试</a></li><li><a href="/interview/Tomcat-FAQ.html" class="sidebar-link">Tomcat 面试</a></li></ul> </aside> <div class="password-shadow password-wrapper-in" style="display:none;" data-v-68139a52 data-v-3ba18f14><h3 class="title" style="display:none;" data-v-68139a52 data-v-68139a52></h3> <!----> <label id="box" class="inputBox" style="display:none;" data-v-68139a52 data-v-68139a52><input type="password" value="" data-v-68139a52> <span data-v-68139a52>Konck! Knock!</span> <button data-v-68139a52>OK</button></label> <div class="footer" style="display:none;" data-v-68139a52 data-v-68139a52><span data-v-68139a52><i class="iconfont reco-theme" data-v-68139a52></i> <a target="blank" href="https://vuepress-theme-reco.recoluan.com" data-v-68139a52>vuePress-theme-reco</a></span> <span data-v-68139a52><i class="iconfont reco-copyright" data-v-68139a52></i> <a data-v-68139a52><span data-v-68139a52>海星</span>
            
          <!---->
          2020
        </a></span></div></div> <div data-v-3ba18f14><main class="page"><div class="page-title" style="display:none;"><h1 class="title"></h1> <div data-v-5d8dbdb4><i class="iconfont reco-account" data-v-5d8dbdb4><span data-v-5d8dbdb4>海星</span></i> <!----> <!----> <!----></div></div> <div class="theme-reco-content content__default" style="display:none;"><p>请谈谈你对 OOM 的认识？</p> <p>GC 垃圾回收算法和垃圾收集器的关系？分别是什么请你谈谈？</p> <p>怎么查看服务器默认的垃圾收集器是哪个？生产上如何配置垃圾收集器的？谈谈你对垃圾收集器的理解？</p> <p>G1 垃圾收集器？</p> <p>生产环境服务器变慢，诊断思路和性能评估谈谈？</p> <p>假如生产环境出现 CPU 占用过高，请谈谈你的分析思路和定位</p> <h2 id="类加载子系统"><a href="#类加载子系统" class="header-anchor">#</a> 类加载子系统</h2> <h3 id="类加载机制-类加载过程"><a href="#类加载机制-类加载过程" class="header-anchor">#</a> 类加载机制？类加载过程</h3> <p>Java 虚拟机把描述类的数据从 Class 文件加载到内存，并对数据进行校验、转换解析和初始化，最终形成可以被虚拟机直接使用的 Java 类型，这就是虚拟机的加载机制</p> <p>类从被加载到虚拟机内存中开始，到卸载出内存为止，它的整个生命周期包括：<strong>加载、验证、准备、解析、初始化、使用和卸载</strong>七个阶段。(验证、准备和解析又统称为连接，为了支持Java语言的<strong>运行时绑定</strong>，所以<strong>解析阶段也可以是在初始化之后进行的</strong>。以上顺序都只是说开始的顺序，实际过程中是交叉的混合式进行的，加载过程中可能就已经开始验证了)</p> <h3 id="什么是类加载器-类加载器有哪些-这些类加载器都加载哪些文件"><a href="#什么是类加载器-类加载器有哪些-这些类加载器都加载哪些文件" class="header-anchor">#</a> 什么是类加载器，类加载器有哪些？这些类加载器都加载哪些文件？</h3> <h4 id="启动类加载器-引导类加载器-bootstrap-classloader"><a href="#启动类加载器-引导类加载器-bootstrap-classloader" class="header-anchor">#</a> 启动类加载器（引导类加载器，Bootstrap ClassLoader）</h4> <ul><li>这个类加载使用 C/C++ 语言实现，嵌套在 JVM 内部</li> <li>它用来加载 Java 的核心库（<code>JAVA_HOME/jre/lib/rt.jar</code>、<code>resource.jar</code>或<code>sun.boot.class.path</code>路径下的内容），用于提供 JVM 自身需要的类</li> <li>并不继承自 <code>java.lang.ClassLoader</code>，没有父加载器</li> <li>加载扩展类和应用程序类加载器，并指定为他们的父类加载器</li> <li>出于安全考虑，Bootstrap 启动类加载器只加载名为java、Javax、sun等开头的类</li></ul> <h4 id="扩展类加载器-extension-classloader"><a href="#扩展类加载器-extension-classloader" class="header-anchor">#</a> 扩展类加载器（Extension ClassLoader）</h4> <ul><li>Java 语言编写，由<code>sun.misc.Launcher$ExtClassLoader</code>实现</li> <li>派生于 ClassLoader</li> <li>父类加载器为启动类加载器</li> <li>从 <code>java.ext.dirs</code> 系统属性所指定的目录中加载类库，或从 JDK 的安装目录的<code>jre/lib/ext</code> 子目录（扩展目录）下加载类库。如果用户创建的 JAR 放在此目录下，也会自动由扩展类加载器加载</li></ul> <h4 id="应用程序类加载器-也叫系统类加载器-appclassloader"><a href="#应用程序类加载器-也叫系统类加载器-appclassloader" class="header-anchor">#</a> 应用程序类加载器（也叫系统类加载器，AppClassLoader）</h4> <ul><li>Java 语言编写，由 <code>sun.misc.Lanucher$AppClassLoader</code> 实现</li> <li>派生于 ClassLoader</li> <li>父类加载器为扩展类加载器</li> <li>它负责加载环境变量<code>classpath</code>或系统属性<code>java.class.path</code> 指定路径下的类库</li> <li>该类加载是<strong>程序中默认的类加载器</strong>，一般来说，Java 应用的类都是由它来完成加载的</li> <li>通过 <code>ClassLoader#getSystemClassLoader()</code> 方法可以获取到该类加载器</li></ul> <h4 id="用户自定义类加载器"><a href="#用户自定义类加载器" class="header-anchor">#</a> 用户自定义类加载器</h4> <p>在 Java 的日常应用程序开发中，类的加载几乎是由 3 种类加载器相互配合执行的，在必要时，我们还可以自定义类加载器，来定制类的加载方式</p> <h5 id="为什么要自定义类加载器"><a href="#为什么要自定义类加载器" class="header-anchor">#</a> 为什么要自定义类加载器？</h5> <ul><li>隔离加载类</li> <li>修改类加载的方式</li> <li>扩展加载源（可以从数据库、云端等指定来源加载类）</li> <li>防止源码泄露（Java 代码容易被反编译，如果加密后，自定义加载器加载类的时候就可以先解密，再加载）</li></ul> <h3 id="多线程的情况下-类的加载为什么不会出现重复加载的情况"><a href="#多线程的情况下-类的加载为什么不会出现重复加载的情况" class="header-anchor">#</a> 多线程的情况下，类的加载为什么不会出现重复加载的情况？</h3> <p>双亲委派</p> <h3 id="什么是双亲委派机制-它有啥优势-可以打破这种机制吗"><a href="#什么是双亲委派机制-它有啥优势-可以打破这种机制吗" class="header-anchor">#</a> 什么是双亲委派机制？它有啥优势？可以打破这种机制吗？</h3> <p>Java 虚拟机对 class 文件采用的是<strong>按需加载</strong>的方式，也就是说当需要使用该类的时候才会将它的 class 文件加载到内存生成 class 对象。而且加载某个类的 class 文件时，Java 虚拟机采用的是双亲委派模式，即把请求交给父类处理，它是一种任务委派模式。</p> <p><strong>工作过程</strong></p> <ul><li>如果一个类加载器收到了类加载请求，它并不会自己先去加载，而是把这个请求委托给父类的加载器去执行；</li> <li>如果父类加载器还存在其父类加载器，则进一步向上委托，依次递归，请求最终将到达顶层的启动类加载器；</li> <li>如果父类加载器可以完成类加载任务，就成功返回，倘若父类加载器无法完成此加载任务，子加载器才会尝试自己去加载，这就是双亲委派模式</li></ul> <p><strong>优势</strong></p> <ul><li>避免类的重复加载，JVM 中区分不同类，不仅仅是根据类名，相同的 class 文件被不同的 ClassLoader 加载就属于两个不同的类（比如，Java中的Object类，无论哪一个类加载器要加载这个类，最终都是委派给处于模型最顶端的启动类加载器进行加载，如果不采用双亲委派模型，由各个类加载器自己去加载的话，系统中会存在多种不同的 Object 类）</li> <li>保护程序安全，防止核心 API 被随意篡改，避免用户自己编写的类动态替换 Java 的一些核心类，比如我们自定义类：<code>java.lang.String</code></li></ul> <h3 id="自定义了一个string-那么会加载哪个string"><a href="#自定义了一个string-那么会加载哪个string" class="header-anchor">#</a> 自定义了一个String，那么会加载哪个String？</h3> <p>针对java.*开头的类，jvm的实现中已经保证了必须由bootstrp来加载</p> <h3 id="简单说说你了解的类加载器-可以打破双亲委派么-怎么打破。"><a href="#简单说说你了解的类加载器-可以打破双亲委派么-怎么打破。" class="header-anchor">#</a> 简单说说你了解的类加载器，可以打破双亲委派么，怎么打破。</h3> <p><strong>思路：</strong> 先说明一下什么是类加载器，可以给面试官画个图，再说一下类加载器存在的意义，说一下双亲委派模型，最后阐述怎么打破双亲委派模型。</p> <p><strong>我的答案：</strong></p> <h4 id="_1-什么是类加载器"><a href="#_1-什么是类加载器" class="header-anchor">#</a> 1) 什么是类加载器？</h4> <p><strong>类加载器</strong> 就是根据指定全限定名称将class文件加载到JVM内存，转为Class对象。</p> <blockquote><ul><li>启动类加载器（Bootstrap  ClassLoader）：由C++语言实现（针对HotSpot）,负责将存放在&lt;JAVA_HOME&gt;\lib目录或-Xbootclasspath参数指定的路径中的类库加载到内存中。</li> <li>其他类加载器：由Java语言实现，继承自抽象类ClassLoader。如：</li></ul> <blockquote><ul><li>扩展类加载器（Extension ClassLoader）：负责加载&lt;JAVA_HOME&gt;\lib\ext目录或java.ext.dirs系统变量指定的路径中的所有类库。</li> <li>应用程序类加载器（Application ClassLoader）。负责加载用户类路径（classpath）上的指定类库，我们可以直接使用这个类加载器。一般情况，如果我们没有自定义类加载器默认就是用这个加载器。</li></ul></blockquote></blockquote> <h4 id="_2-双亲委派模型"><a href="#_2-双亲委派模型" class="header-anchor">#</a> 2）双亲委派模型</h4> <p><strong>双亲委派模型工作过程是：</strong></p> <blockquote><p>如果一个类加载器收到类加载的请求，它首先不会自己去尝试加载这个类，而是把这个请求委派给父类加载器完成。每个类加载器都是如此，只有当父加载器在自己的搜索范围内找不到指定的类时（即ClassNotFoundException），子加载器才会尝试自己去加载。</p></blockquote> <p>双亲委派模型图：</p> <p><img src="https://user-gold-cdn.xitu.io/2019/7/23/16c1c54cf4ad886b?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p> <h4 id="_3-为什么需要双亲委派模型"><a href="#_3-为什么需要双亲委派模型" class="header-anchor">#</a> 3）为什么需要双亲委派模型？</h4> <p>在这里，先想一下，如果没有双亲委派，那么用户是不是可以<strong>自己定义一个java.lang.Object的同名类</strong>，<strong>java.lang.String的同名类</strong>，并把它放到ClassPath中,那么<strong>类之间的比较结果及类的唯一性将无法保证</strong>，因此，为什么需要双亲委派模型？<strong>防止内存中出现多份同样的字节码</strong></p> <h4 id="_4-怎么打破双亲委派模型"><a href="#_4-怎么打破双亲委派模型" class="header-anchor">#</a> 4）怎么打破双亲委派模型？</h4> <p>打破双亲委派机制则不仅<strong>要继承ClassLoader</strong>类，还要<strong>重写loadClass和findClass</strong>方法。</p> <hr> <hr> <h2 id="内存管理"><a href="#内存管理" class="header-anchor">#</a> 内存管理</h2> <h3 id="java内存结构"><a href="#java内存结构" class="header-anchor">#</a> Java内存结构？</h3> <p><img src="https://user-gold-cdn.xitu.io/2019/7/8/16bd08c33a3d751b?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt=""></p> <p>方法区和堆是所有线程共享的内存区域；而Java栈、本地方法栈和程序计数器是线程私有的内存区域。</p> <ul><li>Java堆是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域，在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例，几乎所有的对象实例都在这里分配内存。</li> <li>方法区用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。</li> <li>程序计数器（Program Counter Register）是一块较小的内存空间，它的作用可以看做是当前线程所执行的字节码的行号指示器。</li> <li>JVM栈（JVM Stacks）,与程序计数器一样，也是线程私有的，它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型：每个方法被执行的时候都会同时创建一个栈帧（Stack Frame）用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程，就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。</li> <li>本地方法栈（Native Method Stacks）与虚拟机栈所发挥的作用是非常相似的，其区别不过是虚拟机栈为虚拟机执行Java方法（也就是字节码）服务，而本地方法栈则是为虚拟机使用到的Native方法服务。</li></ul> <h3 id="内存泄露和内存溢出的区别"><a href="#内存泄露和内存溢出的区别" class="header-anchor">#</a> 内存泄露和内存溢出的区别？</h3> <p>内存溢出 out of memory，是指程序在申请内存时，没有足够的内存空间供其使用，出现out of memory；比如申请了一个integer,但给它存了long才能存下的数，那就是内存溢出。</p> <p>内存泄露 memory leak，是指程序在申请内存后，无法释放已申请的内存空间，一次内存泄露危害可以忽略，但内存泄露堆积后果很严重，无论多少内存,迟早会被占光。</p> <p>memory leak会最终会导致out of memory！</p> <h3 id="什么情况下会发生栈内存溢出"><a href="#什么情况下会发生栈内存溢出" class="header-anchor">#</a> 什么情况下会发生栈内存溢出?</h3> <ul><li>栈是线程私有的，他的生命周期与线程相同，每个方法在执行的时候都会创建一个栈帧，用来存储局部变量表，操作数栈，动态链接，方法出口等信息。局部变量表又包含基本数据类型，对象引用类型</li> <li>如果线程请求的栈深度大于虚拟机所允许的最大深度，将抛出StackOverflowError异常，方法递归调用产生这种结果。</li> <li>如果Java虚拟机栈可以动态扩展，并且扩展的动作已经尝试过，但是无法申请到足够的内存去完成扩展，或者在新建立线程的时候没有足够的内存去创建对应的虚拟机栈，那么Java虚拟机将抛出一个OutOfMemory 异常。(线程启动过多)</li> <li>参数 -Xss 去调整JVM栈的大小</li></ul> <h3 id="jvm内存为什么要分成新生代-老年代-持久代。新生代中为什么要分为eden和survivor。"><a href="#jvm内存为什么要分成新生代-老年代-持久代。新生代中为什么要分为eden和survivor。" class="header-anchor">#</a> JVM内存为什么要分成新生代，老年代，持久代。新生代中为什么要分为Eden和Survivor。</h3> <h4 id="_1-共享内存区划分"><a href="#_1-共享内存区划分" class="header-anchor">#</a> 1）共享内存区划分</h4> <ul><li>共享内存区 = 持久带 + 堆</li> <li>持久带 = 方法区 + 其他</li> <li>Java堆 = 老年代 + 新生代</li> <li>新生代 = Eden + S0 + S1</li></ul> <h4 id="_2-一些参数的配置"><a href="#_2-一些参数的配置" class="header-anchor">#</a> 2）一些参数的配置</h4> <ul><li>默认的，新生代 ( Young ) 与老年代 ( Old ) 的比例的值为 1:2 ，可以通过参数 –XX:NewRatio 配置。</li> <li>默认的，Edem : from : to = 8 : 1 : 1 ( 可以通过参数 –XX:SurvivorRatio 来设定)</li> <li>Survivor区中的对象被复制次数为15(对应虚拟机参数 -XX:+MaxTenuringThreshold)</li></ul> <h4 id="_3-为什么要分为eden和survivor-为什么要设置两个survivor区"><a href="#_3-为什么要分为eden和survivor-为什么要设置两个survivor区" class="header-anchor">#</a> 3)为什么要分为Eden和Survivor?为什么要设置两个Survivor区？</h4> <ul><li>如果没有Survivor，Eden区每进行一次Minor GC，存活的对象就会被送到老年代。老年代很快被填满，触发Major GC.老年代的内存空间远大于新生代，进行一次Full GC消耗的时间比Minor GC长得多,所以需要分为Eden和Survivor。</li> <li>Survivor的存在意义，就是减少被送到老年代的对象，进而减少Full GC的发生，Survivor的预筛选保证，只有经历16次Minor GC还能在新生代中存活的对象，才会被送到老年代。</li> <li>设置两个Survivor区最大的好处就是解决了碎片化，刚刚新建的对象在Eden中，经历一次Minor GC，Eden中的存活对象就会被移动到第一块survivor space S0，Eden被清空；等Eden区再满了，就再触发一次Minor GC，Eden和S0中的存活对象又会被复制送入第二块survivor space S1（这个过程非常重要，因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间，避免了碎片化的发生）</li></ul> <hr> <h2 id="gc"><a href="#gc" class="header-anchor">#</a> GC</h2> <h3 id="_1-jvm-垃圾回收的时候如何确定垃圾-你知道什么是-gc-roots-吗-gc-roots-如何确定-那些对象可以作为-gc-roots"><a href="#_1-jvm-垃圾回收的时候如何确定垃圾-你知道什么是-gc-roots-吗-gc-roots-如何确定-那些对象可以作为-gc-roots" class="header-anchor">#</a> 1. JVM 垃圾回收的时候如何确定垃圾？ 你知道什么是 GC Roots 吗？GC Roots 如何确定，那些对象可以作为 GC Roots?</h3> <p>内存中不再使用的空间就是垃圾</p> <p>引用计数法和可达性分析</p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdeam8z27oj31e60mudzv.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdeaofj7tsj31cs0nstsz.jpg" alt=""></p> <p>哪些对象可以作为 GC Root 呢，有以下几类</p> <ul><li>虚拟机栈（栈帧中的本地变量表）中引用的对象</li> <li>方法区中类静态属性引用的对象</li> <li>方法区中常量引用的对象</li> <li>本地方法栈中 JNI（即一般说的 Native 方法）引用的对象</li></ul> <h3 id="jvm中一次完整的gc流程是怎样的-对象如何晋升到老年代"><a href="#jvm中一次完整的gc流程是怎样的-对象如何晋升到老年代" class="header-anchor">#</a> JVM中一次完整的GC流程是怎样的，对象如何晋升到老年代</h3> <p><strong>思路：</strong> 先描述一下Java堆内存划分，再解释Minor GC，Major GC，full GC，描述它们之间转化流程。</p> <p><strong>我的答案：</strong></p> <ul><li>Java堆 = 老年代 + 新生代</li> <li>新生代 = Eden + S0 + S1</li> <li>当 Eden 区的空间满了， Java虚拟机会触发一次 Minor GC，以收集新生代的垃圾，存活下来的对象，则会转移到 Survivor区。</li> <li><strong>大对象</strong>（需要大量连续内存空间的Java对象，如那种很长的字符串）<strong>直接进入老年态</strong>；</li> <li>如果对象在Eden出生，并经过第一次Minor GC后仍然存活，并且被Survivor容纳的话，年龄设为1，每熬过一次Minor GC，年龄+1，<strong>若年龄超过一定限制（15），则被晋升到老年态</strong>。即<strong>长期存活的对象进入老年态</strong>。</li> <li>老年代满了而<strong>无法容纳更多的对象</strong>，Minor GC 之后通常就会进行Full GC，Full GC  清理整个内存堆 – <strong>包括年轻代和年老代</strong>。</li> <li>Major GC <strong>发生在老年代的GC</strong>，<strong>清理老年区</strong>，经常会伴随至少一次Minor GC，<strong>比Minor GC慢10倍以上</strong>。</li></ul> <h3 id="你知道哪几种垃圾收集器-各自的优缺点-重点讲下cms和g1-包括原理-流程-优缺点。"><a href="#你知道哪几种垃圾收集器-各自的优缺点-重点讲下cms和g1-包括原理-流程-优缺点。" class="header-anchor">#</a> 你知道哪几种垃圾收集器，各自的优缺点，重点讲下cms和G1，包括原理，流程，优缺点。</h3> <p><strong>思路：</strong> 一定要记住典型的垃圾收集器，尤其cms和G1，它们的原理与区别，涉及的垃圾回收算法。</p> <p><strong>我的答案：</strong></p> <h4 id="_1-几种垃圾收集器"><a href="#_1-几种垃圾收集器" class="header-anchor">#</a> 1）几种垃圾收集器：</h4> <ul><li><strong>Serial收集器：</strong> 单线程的收集器，收集垃圾时，必须stop the world，使用复制算法。</li> <li><strong>ParNew收集器：</strong>  Serial收集器的多线程版本，也需要stop the world，复制算法。</li> <li><strong>Parallel Scavenge收集器：</strong> 新生代收集器，复制算法的收集器，并发的多线程收集器，目标是达到一个可控的吞吐量。如果虚拟机总共运行100分钟，其中垃圾花掉1分钟，吞吐量就是99%。</li> <li><strong>Serial Old收集器：</strong> 是Serial收集器的老年代版本，单线程收集器，使用标记整理算法。</li> <li><strong>Parallel Old收集器：</strong> 是Parallel Scavenge收集器的老年代版本，使用多线程，标记-整理算法。</li> <li><strong>CMS(Concurrent Mark Sweep) 收集器：</strong> 是一种以获得最短回收停顿时间为目标的收集器，<strong>标记清除算法，运作过程：初始标记，并发标记，重新标记，并发清除</strong>，收集结束会产生大量空间碎片。</li> <li><strong>G1收集器：</strong> 标记整理算法实现，<strong>运作流程主要包括以下：初始标记，并发标记，最终标记，筛选标记</strong>。不会产生空间碎片，可以精确地控制停顿。</li></ul> <h4 id="_2-cms收集器和g1收集器的区别"><a href="#_2-cms收集器和g1收集器的区别" class="header-anchor">#</a> 2）CMS收集器和G1收集器的区别：</h4> <ul><li>CMS收集器是老年代的收集器，可以配合新生代的Serial和ParNew收集器一起使用；</li> <li>G1收集器收集范围是老年代和新生代，不需要结合其他收集器使用；</li> <li>CMS收集器以最小的停顿时间为目标的收集器；</li> <li>G1收集器可预测垃圾回收的停顿时间</li> <li>CMS收集器是使用“标记-清除”算法进行的垃圾回收，容易产生内存碎片</li> <li>G1收集器使用的是“标记-整理”算法，进行了空间整合，降低了内存空间碎片。</li></ul> <h3 id=""><a href="#" class="header-anchor">#</a></h3> <h3 id="说说你知道的几种主要的jvm参数"><a href="#说说你知道的几种主要的jvm参数" class="header-anchor">#</a> 说说你知道的几种主要的JVM参数</h3> <p><strong>思路：</strong> 可以说一下堆栈配置相关的，垃圾收集器相关的，还有一下辅助信息相关的。</p> <p><strong>我的答案：</strong></p> <h4 id="_1-堆栈配置相关"><a href="#_1-堆栈配置相关" class="header-anchor">#</a> 1）堆栈配置相关</h4> <div class="language- extra-class"><pre class="language-text"><code>java -Xmx3550m -Xms3550m -Xmn2g -Xss128k 
-XX:MaxPermSize=16m -XX:NewRatio=4 -XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=0
复制代码
</code></pre></div><p><strong>-Xmx3550m：</strong> 最大堆大小为3550m。</p> <p><strong>-Xms3550m：</strong> 设置初始堆大小为3550m。</p> <p><strong>-Xmn2g：</strong> 设置年轻代大小为2g。</p> <p><strong>-Xss128k：</strong> 每个线程的堆栈大小为128k。</p> <p><strong>-XX:MaxPermSize：</strong>  设置持久代大小为16m</p> <p><strong>-XX:NewRatio=4:</strong> 设置年轻代（包括Eden和两个Survivor区）与年老代的比值（除去持久代）。</p> <p><strong>-XX:SurvivorRatio=4：</strong> 设置年轻代中Eden区与Survivor区的大小比值。设置为4，则两个Survivor区与一个Eden区的比值为2:4，一个Survivor区占整个年轻代的1/6</p> <p><strong>-XX:MaxTenuringThreshold=0：</strong> 设置垃圾最大年龄。如果设置为0的话，则年轻代对象不经过Survivor区，直接进入年老代。</p> <h4 id="_2-垃圾收集器相关"><a href="#_2-垃圾收集器相关" class="header-anchor">#</a> 2）垃圾收集器相关</h4> <div class="language- extra-class"><pre class="language-text"><code>-XX:+UseParallelGC
-XX:ParallelGCThreads=20
-XX:+UseConcMarkSweepGC 
-XX:CMSFullGCsBeforeCompaction=5
-XX:+UseCMSCompactAtFullCollection：
复制代码
</code></pre></div><p><strong>-XX:+UseParallelGC：</strong> 选择垃圾收集器为并行收集器。</p> <p><strong>-XX:ParallelGCThreads=20：</strong> 配置并行收集器的线程数</p> <p><strong>-XX:+UseConcMarkSweepGC：</strong> 设置年老代为并发收集。</p> <p><strong>-XX:CMSFullGCsBeforeCompaction</strong>：由于并发收集器不对内存空间进行压缩、整理，所以运行一段时间以后会产生“碎片”，使得运行效率降低。此值设置运行多少次GC以后对内存空间进行压缩、整理。</p> <p><strong>-XX:+UseCMSCompactAtFullCollection：</strong> 打开对年老代的压缩。可能会影响性能，但是可以消除碎片</p> <h4 id="_3-辅助信息相关"><a href="#_3-辅助信息相关" class="header-anchor">#</a> 3）辅助信息相关</h4> <div class="language- extra-class"><pre class="language-text"><code>-XX:+PrintGC
-XX:+PrintGCDetails
复制代码
</code></pre></div><p><strong>-XX:+PrintGC 输出形式:</strong></p> <p>[GC 118250K-&gt;113543K(130112K), 0.0094143 secs] [Full GC 121376K-&gt;10414K(130112K), 0.0650971 secs]</p> <p><strong>-XX:+PrintGCDetails 输出形式:</strong></p> <p>[GC [DefNew: 8614K-&gt;781K(9088K), 0.0123035 secs] 118250K-&gt;113543K(130112K), 0.0124633 secs] [GC [DefNew: 8614K-&gt;8614K(9088K), 0.0000665 secs][Tenured: 112761K-&gt;10414K(121024K), 0.0433488 secs] 121376K-&gt;10414K(130112K), 0.0436268 secs</p> <h3 id="怎么打出线程栈信息。"><a href="#怎么打出线程栈信息。" class="header-anchor">#</a> 怎么打出线程栈信息。</h3> <p><strong>思路：</strong> 可以说一下jps，top ，jstack这几个命令，再配合一次排查线上问题进行解答。</p> <p><strong>我的答案：</strong></p> <ul><li>输入jps，获得进程号。</li> <li>top -Hp pid 获取本进程中所有线程的CPU耗时性能</li> <li>jstack pid命令查看当前java进程的堆栈状态</li> <li>或者 jstack -l  &gt; /tmp/output.txt 把堆栈信息打到一个txt文件。</li> <li>可以使用fastthread 堆栈定位，<a href="http://fastthread.io/" target="_blank" rel="noopener noreferrer">fastthread.io/<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdeadup0v1j30xk0lgncn.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdeambp5abj31ew0pm16q.jpg" alt=""></p> <hr> <h2 id="调优"><a href="#调优" class="header-anchor">#</a> 调优</h2> <h2 id="_2-你说你做过-jvm-调优和参数配置-请问如何盘点查看-jvm-系统默认值"><a href="#_2-你说你做过-jvm-调优和参数配置-请问如何盘点查看-jvm-系统默认值" class="header-anchor">#</a> 2.你说你做过 JVM 调优和参数配置，请问如何盘点查看 JVM 系统默认值</h2> <h3 id="jvm参数类型"><a href="#jvm参数类型" class="header-anchor">#</a> JVM参数类型</h3> <ul><li><p>标配参数</p> <ul><li>-version   (java -version)</li> <li>-help       (java -help)</li> <li>java -showversion</li></ul></li> <li><p>X 参数（了解）</p> <ul><li><p>-Xint 解释执行</p></li> <li><p>-Xcomp 第一次使用就编译成本地代码</p></li> <li><p>-Xmixed 混合模式</p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdeb84yh71j30yq0j6akl.jpg" alt=""></p></li></ul></li> <li><p>xx参数</p> <ul><li><p>Boolean 类型</p> <ul><li><p>公式： -xx:+ 或者 - 某个属性值（+表示开启，- 表示关闭）</p></li> <li><p>Case</p> <ul><li><p>是否打印GC收集细节</p> <ul><li>-XX:+PrintGCDetails</li> <li>-XX:- PrintGCDetails</li></ul> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdebpozfgwj315o0sgtcy.jpg" alt=""></p> <p>添加如下参数后，重新查看，发现是 + 号了</p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdebrx25moj31170u042c.jpg" alt=""></p></li> <li><p>是否使用串行垃圾回收器</p> <ul><li>-XX:-UseSerialGC</li> <li>-XX:+UseSerialGC</li></ul></li></ul></li></ul></li> <li><p>KV 设值类型</p> <ul><li><p>公式 -XX:属性key=属性 value</p></li> <li><p>Case:</p> <ul><li><p>-XX:MetaspaceSize=128m</p></li> <li><p>-xx:MaxTenuringThreshold=15</p></li> <li><p>我们常见的 -Xms和 -Xmx 也属于 KV 设值类型</p> <ul><li>-Xms 等价于 -XX:InitialHeapSize</li> <li>-Xmx 等价于 -XX:MaxHeapSize</li></ul> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdecj9d7z3j310202qdgb.jpg" alt=""></p></li></ul></li></ul></li> <li><p>jinfo 举例，如何查看当前运行程序的配置</p> <ul><li>jps -l</li> <li>jinfo -flag [配置项] 进程编号</li> <li>jinfo <strong>-flags</strong> 1981(打印所有)</li> <li>jinfo -flag PrintGCDetails 1981</li> <li>jinfo -flag MetaspaceSize 2044</li></ul></li></ul></li></ul> <p>这些都是命令级别的查看，我们如何在程序运行中查看</p> <div class="language-java extra-class"><pre class="language-java"><code>    <span class="token keyword">long</span> totalMemory <span class="token operator">=</span> <span class="token class-name">Runtime</span><span class="token punctuation">.</span><span class="token function">getRuntime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">totalMemory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">long</span> maxMemory <span class="token operator">=</span> <span class="token class-name">Runtime</span><span class="token punctuation">.</span><span class="token function">getRuntime</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">maxMemory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;total_memory(-xms)=&quot;</span><span class="token operator">+</span>totalMemory<span class="token operator">+</span><span class="token string">&quot;字节，&quot;</span> <span class="token operator">+</span><span class="token punctuation">(</span>totalMemory<span class="token operator">/</span><span class="token punctuation">(</span><span class="token keyword">double</span><span class="token punctuation">)</span><span class="token number">1024</span><span class="token operator">/</span><span class="token number">1024</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">&quot;MB&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;max_memory(-xmx)=&quot;</span><span class="token operator">+</span>maxMemory<span class="token operator">+</span><span class="token string">&quot;字节，&quot;</span> <span class="token operator">+</span><span class="token punctuation">(</span>maxMemory<span class="token operator">/</span><span class="token punctuation">(</span><span class="token keyword">double</span><span class="token punctuation">)</span><span class="token number">1024</span><span class="token operator">/</span><span class="token number">1024</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token string">&quot;MB&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
</code></pre></div><h3 id="盘点家底查看jvm默认值"><a href="#盘点家底查看jvm默认值" class="header-anchor">#</a> 盘点家底查看JVM默认值</h3> <ul><li><p>-XX:+PrintFlagsInitial</p> <ul><li><p>主要查看初始默认值</p></li> <li><p>java -XX:+PrintFlagsInitial</p></li> <li><p>java -XX:+PrintFlagsInitial -version</p></li> <li><p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdee0ndg33j31ci0m6k5w.jpg" alt=""></p> <p><strong>等号前有冒号</strong> :=  说明 jvm 参数有人为修改过或者 JVM加载修改</p> <p>false 说明是Boolean 类型 参数，数字说明是 KV 类型参数</p></li></ul></li> <li><p>-XX:+PrintFlagsFinal</p> <ul><li>主要查看修改更新</li> <li>java -XX:+PrintFlagsFinal</li> <li>java -XX:+PrintFlagsFinal -version</li> <li>运行java命令的同时打印出参数 java -XX:+PrintFlagsFinal -XX:MetaspaceSize=512m Hello.java</li></ul></li> <li><p>-XX:+PrintCommondLineFlags</p> <ul><li>打印命令行参数</li> <li>java -XX:+PrintCommondLineFlags -version</li> <li>可以方便的看到垃圾回收器</li> <li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehf1e54soj31e006qjz6.jpg" alt=""></li></ul></li></ul> <h2 id="_3-你平时工作用过的-jvm-常用基本配置参数有哪些"><a href="#_3-你平时工作用过的-jvm-常用基本配置参数有哪些" class="header-anchor">#</a> 3. 你平时工作用过的 JVM 常用基本配置参数有哪些？</h2> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdee0iss88j31eu0n6aqi.jpg" alt=""></p> <ul><li><p>-Xms</p> <ul><li>初始大小内存，默认为物理内存1/64</li> <li>等价于 -XX:InitialHeapSize</li></ul></li> <li><p>-Xmx</p> <ul><li>最大分配内存，默认为物理内存的1/4</li> <li>等价于 -XX:MaxHeapSize</li></ul></li> <li><p>-Xss</p> <ul><li>设置单个线程的大小，一般默认为 512k~1024k</li> <li>等价于 -XX:ThreadStackSize</li> <li>如果通过 <code>jinfo ThreadStackSize 线程 ID</code> 查看会显示为 0，指的是默认出厂设置</li></ul></li> <li><p>-Xmn</p> <ul><li>设置年轻代大小（一般不设置）</li></ul></li> <li><p>-XX:MetaspaceSize</p> <ul><li>设置元空间大小。元空间的本质和永久代类似，都是对 JMM 规范中方法区的实现。不过元空间与永久代最大的区别是，元空间并不在虚拟机中，而是使用本地内存。因此，默认情况下，元空间的大小仅受本地内存限制</li> <li>但是元空间默认也很小，频繁 new 对象，也会 OOM</li> <li>-Xms10m -Xmx10m -XX:MetaspaceSize=1024m -XX:+PrintFlagsFinal</li></ul></li> <li><p>-XX:+PrintGCDetails</p> <ul><li><p>输出详细的 GC 收集日志信息</p></li> <li><p>测试时候，可以将参数调到最小，</p> <p><code>-Xms10m -Xmx10m -XX:+PrintGCDetails</code></p> <p>定义一个大对象，撑爆堆内存，</p> <div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">InterruptedException</span> <span class="token punctuation">{</span>
    <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">&quot;==hello gc===&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">//Thread.sleep(Integer.MAX_VALUE);</span>

    <span class="token comment">//-Xms10m -Xmx10m -XX:PrintGCDetails</span>

    <span class="token keyword">byte</span><span class="token punctuation">[</span><span class="token punctuation">]</span> bytes <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token keyword">byte</span><span class="token punctuation">[</span><span class="token number">11</span> <span class="token operator">*</span> <span class="token number">1024</span> <span class="token operator">*</span> <span class="token number">1024</span><span class="token punctuation">]</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span><span class="token operator">!</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">(</span>https<span class="token operator">:</span><span class="token operator">/</span><span class="token operator">/</span>tva1<span class="token punctuation">.</span>sinaimg<span class="token punctuation">.</span>cn<span class="token operator">/</span>large<span class="token operator">/</span><span class="token number">007</span>S8ZIlly1gehkvas3vzj31a90u0n7t<span class="token punctuation">.</span>jpg<span class="token punctuation">)</span>
</code></pre></div></li> <li><p>GC<img src="https://tva1.sinaimg.cn/large/00831rSTly1gdefrf0dfqj31fs0honjk.jpg" alt=""></p></li> <li><p>Full GC<img src="https://tva1.sinaimg.cn/large/00831rSTly1gdefrc3lmbj31hy0gk7of.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdefr8tvx0j31h60m41eq.jpg" alt=""></p></li></ul></li> <li><p>-XX:SurvivorRatio</p> <ul><li>设置新生代中 eden 和S0/S1空间的比例</li> <li>默认 -XX:SurvivorRatio=8,Eden:S0:S1=8:1:1</li> <li>SurvivorRatio值就是设置 Eden 区的比例占多少，S0/S1相同，如果设置  -XX:SurvivorRatio=2，那Eden:S0:S1=2:1:1</li></ul></li> <li><p>-XX:NewRatio</p> <ul><li>配置年轻代和老年代在堆结构的比例</li> <li>默认 -XX:NewRatio=2，新生代 1，老年代 2，年轻代占整个堆的 1/3</li> <li>NewRatio值就是设置老年代的占比，如果设置-XX:NewRatio=4，那就表示新生代占 1，老年代占 4，年轻代占整个堆的 1/5</li></ul></li> <li><p>-XX:MaxTenuringThreshold</p> <ul><li>设置垃圾的最大年龄（java8 固定设置最大 15）</li> <li><img src="https://tva1.sinaimg.cn/large/00831rSTly1gdefr4xeq1j31g80lek6e.jpg" alt=""></li></ul></li></ul> <p>参数不懂，推荐直接去看官网，</p> <p>https://docs.oracle.com/javacomponents/jrockit-hotspot/migration-guide/cloptions.htm#JRHMG127</p> <p>https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BGBCIEFC</p> <p>https://docs.oracle.com/javase/8/</p> <p>Java SE Tools Reference for UNIX](https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html)</p> <h3 id="_4-强引用、软引用、弱引用、虚引用分别是什么"><a href="#_4-强引用、软引用、弱引用、虚引用分别是什么" class="header-anchor">#</a> 4. 强引用、软引用、弱引用、虚引用分别是什么？</h3> <h2 id="_5-请谈谈你对-oom-的认识"><a href="#_5-请谈谈你对-oom-的认识" class="header-anchor">#</a> 5. 请谈谈你对 OOM 的认识</h2> <ul><li><p>java.lang.StackOverflowError</p> <ul><li><div class="language- extra-class"><pre class="language-text"><code>public class StackOverflowErrorDemo {

    public static void main(String[] args) {
        stackoverflowError();
    }

    private static void stackoverflowError() {
        stackoverflowError();
    }
}
</code></pre></div></li></ul></li> <li><p>java.lang.OutOfMemoryError: Java heap space</p> <ul><li>new个大对象,就会出现</li></ul></li> <li><p>java.lang.OutOfMemoryError: GC overhead limit exceeded  (GC上头，哈哈)</p> <ul><li><p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehmrz0dvaj311w0muk0e.jpg" alt=""></p></li> <li><div class="language-java extra-class"><pre class="language-java"><code><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">StackOverflowErrorDemo</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">stackoverflowError</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">stackoverflowError</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">stackoverflowError</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre></div></li></ul></li> <li><p>java.lang.OutOfMemoryError: Direct buffer memory</p> <ul><li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehn18eix6j31a00m2wup.jpg" alt=""></li> <li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehn52fphnj31as0lidyh.jpg" alt=""></li></ul></li> <li><p>java.lang.OutOfMemoryError: unable to create new native thread</p> <ul><li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehn7osaz1j31940kc4c8.jpg" alt=""></li></ul></li> <li><p>java.lang.OutOfMemoryError：Metaspace</p> <ul><li>http://openjdk.java.net/jeps/122</li> <li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehnc3d4g3j319e0msguj.jpg" alt=""></li> <li><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehndijxo8j31920madt6.jpg" alt=""></li></ul></li></ul> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehmmia4gaj30xw0gudid.jpg" alt=""></p> <h2 id="_6-gc垃圾回收算法和垃圾收集器的关系-分别是什么-请你谈谈"><a href="#_6-gc垃圾回收算法和垃圾收集器的关系-分别是什么-请你谈谈" class="header-anchor">#</a> 6. GC垃圾回收算法和垃圾收集器的关系？分别是什么，请你谈谈？</h2> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1geho5bjeg5j31e409m0xb.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1geho87aqmuj31260dqdl2.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehoafwkoaj31a00my7js.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehobkwiegj31da0mc7ds.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehofhsuglj31a20ka116.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehohen24lj31f20n2du8.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1geholtp9p9j31bu0i8dsm.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehop8c2u8j30uu0kgk46.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehptemx4oj31520js47e.jpg" alt=""></p> <p><img src="https://tva1.sinaimg.cn/large/007S8ZIlly1gehps6jzcsj31go0mok5q.jpg" alt=""></p> <h3 id="_7-怎么查看服务器默认的垃圾收集器是哪个-生产上如何配置垃圾收集器-谈谈你对垃圾收集器的理解"><a href="#_7-怎么查看服务器默认的垃圾收集器是哪个-生产上如何配置垃圾收集器-谈谈你对垃圾收集器的理解" class="header-anchor">#</a> 7.怎么查看服务器默认的垃圾收集器是哪个？生产上如何配置垃圾收集器？谈谈你对垃圾收集器的理解？</h3> <h3 id="_8-g1-垃圾收集器"><a href="#_8-g1-垃圾收集器" class="header-anchor">#</a> 8.G1 垃圾收集器？</h3> <h3 id="_9-生产环境服务器变慢-诊断思路和性能评估谈谈"><a href="#_9-生产环境服务器变慢-诊断思路和性能评估谈谈" class="header-anchor">#</a> 9.生产环境服务器变慢，诊断思路和性能评估谈谈？</h3> <h3 id="_10-假设生产环境出现-cpu占用过高-请谈谈你的分析思路和定位"><a href="#_10-假设生产环境出现-cpu占用过高-请谈谈你的分析思路和定位" class="header-anchor">#</a> 10.假设生产环境出现 CPU占用过高，请谈谈你的分析思路和定位</h3> <h3 id="_11-对于jdk-自带的jvm-监控和性能分析工具用过哪些-你是怎么用的"><a href="#_11-对于jdk-自带的jvm-监控和性能分析工具用过哪些-你是怎么用的" class="header-anchor">#</a> 11. 对于JDK 自带的JVM 监控和性能分析工具用过哪些？你是怎么用的？</h3> <ul><li>jconsole  直接在jdk/bin目录下点击jconsole.exe即可启动</li> <li>VisualVM   jdk/bin目录下面jvisualvm.exe</li></ul> <p>https://www.cnblogs.com/ityouknow/p/6437037.html</p> <h2 id="jmm"><a href="#jmm" class="header-anchor">#</a> JMM</h2> <h3 id="为什么要有内存模型"><a href="#为什么要有内存模型" class="header-anchor">#</a> 为什么要有内存模型</h3> <p>Java虚拟机规范中试图定义一种「 <strong>Java 内存模型</strong>」来<strong>屏蔽掉各种硬件和操作系统的内存访问差异</strong>，以实现<strong>让 Java 程序在各种平台下都能达到一致的内存访问效果</strong>，不必因为不同平台上的物理机的内存模型的差异，对各平台定制化开发程序。</p> <p>Java 内存模型的主要目标是定义程序中各个变量的访问规则，即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。这里的变量与我们写 Java 代码中的变量不同，它包括了实例字段、静态字段和构成数组对象的元素，但不包括局部变量和方法参数，因为他们是线程私有的，不会被共享。</p> <h3 id="jvm内存模型的相关知识了解多少-比如重排序-内存屏障-happen-before-主内存-工作内存。"><a href="#jvm内存模型的相关知识了解多少-比如重排序-内存屏障-happen-before-主内存-工作内存。" class="header-anchor">#</a> JVM内存模型的相关知识了解多少，比如重排序，内存屏障，happen-before，主内存，工作内存。</h3></div> <footer class="page-edit" style="display:none;"><!----> <!----></footer> <!----> <!----> <!----></main> <!----></div></div></div></div><div class="global-ui"><div class="back-to-ceiling" style="right:1rem;bottom:6rem;width:2.5rem;height:2.5rem;border-radius:.25rem;line-height:2.5rem;display:none;" data-v-db14854a data-v-db14854a><svg t="1574745035067" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5404" class="icon" data-v-db14854a><path d="M526.60727968 10.90185116a27.675 27.675 0 0 0-29.21455937 0c-131.36607665 82.28402758-218.69155461 228.01873535-218.69155402 394.07834331a462.20625001 462.20625001 0 0 0 5.36959153 69.94390903c1.00431239 6.55289093-0.34802892 13.13561351-3.76865779 18.80351572-32.63518765 54.11355614-51.75690182 118.55860487-51.7569018 187.94566865a371.06718723 371.06718723 0 0 0 11.50484808 91.98906777c6.53300375 25.50556257 41.68394495 28.14064038 52.69160883 4.22606766 17.37162448-37.73630017 42.14135425-72.50938081 72.80769204-103.21549295 2.18761121 3.04276886 4.15646224 6.24463696 6.40373557 9.22774369a1871.4375 1871.4375 0 0 0 140.04691725 5.34970492 1866.36093723 1866.36093723 0 0 0 140.04691723-5.34970492c2.24727335-2.98310674 4.21612437-6.18497483 6.3937923-9.2178004 30.66633723 30.70611158 55.4360664 65.4791928 72.80769147 103.21549355 11.00766384 23.91457269 46.15860503 21.27949489 52.69160879-4.22606768a371.15156223 371.15156223 0 0 0 11.514792-91.99901164c0-69.36717486-19.13165746-133.82216804-51.75690182-187.92578088-3.42062944-5.66790279-4.76302748-12.26056868-3.76865837-18.80351632a462.20625001 462.20625001 0 0 0 5.36959269-69.943909c-0.00994388-166.08943902-87.32547796-311.81420293-218.6915546-394.09823051zM605.93803103 357.87693858a93.93749974 93.93749974 0 1 1-187.89594924 6.1e-7 93.93749974 93.93749974 0 0 1 187.89594924-6.1e-7z" p-id="5405" data-v-db14854a></path><path d="M429.50777625 765.63860547C429.50777625 803.39355007 466.44236686 1000.39046097 512.00932183 1000.39046097c45.56695499 0 82.4922232-197.00623328 82.5015456-234.7518555 0-37.75494459-36.9345906-68.35043303-82.4922232-68.34111062-45.57627738-0.00932239-82.52019037 30.59548842-82.51086798 68.34111062z" p-id="5406" data-v-db14854a></path></svg></div><!----></div></div>
    <script src="/assets/js/app.447d4224.js" defer></script><script src="/assets/js/3.9d76740c.js" defer></script><script src="/assets/js/1.c4fd7d2e.js" defer></script><script src="/assets/js/102.c9485235.js" defer></script>
  </body>
</html>
